#include "factory.h"

//发文件
int transFile(int new_fd,char *md5_file_name,off_t seek_pos,off_t remaining_file_size)
{
    char path_file_name[1000]="net_root/";
    //拼接文件路径
    strcat(path_file_name,md5_file_name);
    int fd=open(path_file_name,O_RDONLY);
    ERROR_CHECK(fd,-1,"open");

    train_t t;
    //发送remaing_file_size给客户端
    t.size=sizeof(remaining_file_size);
    memcpy(t.buf,&remaining_file_size,sizeof(remaining_file_size));
    send(new_fd,&t,4+t.size,0);

    //通过sendfile发送文件内容，从seek_pos开始发
    long ret;
    if(seek_pos)
    {
        ret=sendfile(new_fd,fd,&seek_pos,remaining_file_size);
        ERROR_CHECK(ret,-1,"sendfile");        
    }else{
        ret=sendfile(new_fd,fd,NULL,remaining_file_size);
        ERROR_CHECK(ret,-1,"sendfile");        
    }
    close(fd);
    return 0;
}

//接收文件
off_t recvFile(int new_fd,char *md5_file_name)
{
    //先接文件名
    int recvLen;
    char path_file_name[1000]="net_root/";
    int ret;

    strcat(path_file_name,md5_file_name);
    int fd=open(path_file_name,O_RDWR|O_CREAT,0666);
    ERROR_CHECK(fd,-1,"open");

    //接文件大小
    off_t fileSize;//总长度
    recvn(new_fd,&recvLen,4);
    recvn(new_fd,&fileSize,recvLen);
    struct timeval start,end;
    gettimeofday(&start,NULL);
    off_t downLoadSize=0;
    off_t lastSize=0;
    off_t slice=fileSize/100;//每百分之一

    int pipefds[2];
    pipe(pipefds);//初始化管道
    int total=0;
    while(total<fileSize)
    {
        int ret=splice(new_fd,NULL,pipefds[1],NULL,4096,SPLICE_F_MORE);
        if(ret==0)
        {
            printf("对方断开了\n");
            break;
        }
        total+=ret;
        if(total-lastSize>slice)
        {
            printf("%5.2lf%%\r",100.0*total/fileSize);
            fflush(stdout);
            lastSize=total;
        }
        //从管道中读取数据，写入到文件
        ret=splice(pipefds[0],NULL,fd,NULL,ret,SPLICE_F_MORE);
        if(ret==0)
        {
            printf("对方断开了\n");
            break;
        }
    }
    printf("100.00%%\n");
    gettimeofday(&end,NULL);
    //统计下载总时间(单位：u秒)
    printf("use time=%ld\n",(end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec);
    close(fd);
    return fileSize;
}

//（调用）循环接收
int recvn(int new_fd,void *pStart,int len)
{
    int total=0,ret;
    char *p=(char *)pStart;
    while(total<len)
    {
        ret=recv(new_fd,p+total,len-total,0);
        ERROR_CHECK(ret,-1,"recv");
        if(0==ret)
        {
            printf("对方断开了\n");
            return -1;
        }
        total+=ret;
    }
    return 0;
}

//buf是不同的结构体，发数据
int send_protocal(int new_fd,int control_code,void *pdata,int send_len)
{
    protocol_t t;
    int ret;
    t.size=send_len;
    t.control_code=control_code;
    if(pdata)
    {
        memcpy(t.buf,pdata,send_len);
    }
    ret=send(new_fd,&t,8+t.size,0);
    ERROR_CHECK(ret,-1,"send");
    return 0;
}

//收数据
int recv_protocal(int new_fd,int *control_code,void *pdata)
{
    int recvLen;
    int ret;
    ret=recvn(new_fd,&recvLen,4);
    if(-1==ret)
    {
        return -1;
    }
    ret=recvn(new_fd,control_code,4);//接控制码
    if(-1==ret)
    {
        return -1;
    }
    ret=recvn(new_fd,pdata,recvLen);
    if(-1==ret)
    {
        return -1;
    }
    return 0;
}

